package ssi.peeno;

import java.util.StringTokenizer;

import ssi.peeno.ciphers.AsymCipher;
import ssi.peeno.managers.ConfigManager;
import ssi.peeno.messages.lowlevel.KeyRecoveryMessage;
import ssi.peeno.messages.lowlevel.LowLevelMessage;
import ssi.peeno.messages.lowlevel.LowMessage;
import ssi.peeno.messages.lowlevel.RegAckMessage;
import ssi.peeno.messages.lowlevel.RegMessage;
import ssi.peeno.messages.lowlevel.SynMessage;
import ssi.peeno.messages.lowlevel.SynAckMessage;

public class RequestParser {
	public LowLevelMessage process(String msg, int workerState)
			throws Exception {
		if (workerState == 0) {
			return null;
		} else if (workerState == 1) { // REG
			return parseRegMessage(msg);
		} else if (workerState == 2) {// REG/ACK
			return parseRegAckMessage(msg);
		}
		return null;
	}

	private RegAckMessage parseRegAckMessage(String msg) {
		RegAckMessage regAck = new RegAckMessage();
		StringTokenizer st = new StringTokenizer(msg, "!-!");
		regAck.setUserame(st.nextToken());
		regAck.setR(Integer.parseInt(st.nextToken()));
		return regAck;
	}

	private LowMessage parseLowMessage(StringTokenizer st) {
		// TODO Auto-generated method stub
		return null;
	}

	public SynMessage parseSynMessage(String msg) {
		SynMessage sMsg = new SynMessage();
		StringTokenizer st = new StringTokenizer(msg, "!-!");
		sMsg.setUsername(st.nextToken());
		sMsg.setPassword(st.nextToken());
		sMsg.setTimeStamp(Long.parseLong(st.nextToken()));
		return sMsg;
	}

	private RegMessage parseRegMessage(String msg) throws Exception {
		RegMessage reg = new RegMessage();
		String[] msgpart = msg.split("\r\n");
		// TODO decrypt message first
		/*
		 * msgpart[0] username-email-password msgpart[1] keyLen msgpart[2]...
		 * key
		 */
		int keyLen = Integer.parseInt(msgpart[1]);
		String keyString = msg.substring(msg.length() - keyLen);
		ConfigManager.log(keyString);
		ConfigManager.log(msg);
		StringTokenizer st = new StringTokenizer(msgpart[0], "!-!");
		if (st.countTokens() < 4)
			System.out
					.println("Error in parsing RegMessage, maybe a nullpointerexc will follow");
		reg.setUsername(st.nextToken());
		reg.setEmail(st.nextToken());
		reg.setPassword(st.nextToken());
		reg.setTimestamp(Long.parseLong(st.nextToken()));
		reg.setPubKey(AsymCipher.getPubKeyFromString(keyString));
		reg.setCryptedPriv(st.nextToken());
		return reg;
	}

	public SynAckMessage parseSynAckMessage(String msg) {
		SynAckMessage sackMsg = new SynAckMessage();
		StringTokenizer st = new StringTokenizer(msg, "!-!");
		String tsC = st.nextToken();
		if (!tsC.isEmpty())
			sackMsg.setTimestampClient(Long.parseLong(tsC));
		String tsS = st.nextToken();
		if (!tsS.isEmpty())
			sackMsg.setTimestampServer(Long.parseLong(tsS));
		String sessId = st.nextToken();
		if (!sessId.isEmpty())
			sackMsg.setSessionId(Integer.parseInt(sessId));
		String sessKey = st.nextToken();
		if (!sessKey.isEmpty())
			sackMsg.setSessionKey(sessKey);
		return sackMsg;
	}

	/**
	 * Parse a Msg
	 * 
	 * @param msg String
	 * @return HighLevelMessage
	 */
	public LowMessage parseMsgMessage(String msg) {
		StringTokenizer st = new StringTokenizer(msg, "!-!");
		LowMessage lmsg = new LowMessage();
		lmsg.setMsgId(Integer.parseInt(st.nextToken()));
		lmsg.setPayload(st.nextToken());
		return lmsg;
	}

	public KeyRecoveryMessage parseRecMessage(String msg) {
		StringTokenizer st = new StringTokenizer(msg, "!-!");
		KeyRecoveryMessage krmsg=new KeyRecoveryMessage();
		krmsg.setUsername(st.nextToken());
		krmsg.setCryptedPwd(st.nextToken());
		krmsg.setTimestamp(Long.parseLong(st.nextToken()));
		return krmsg;
	}
}
